//
//  COChatMsgManager.swift
//  CocoProject
//
//  Created by Vill on 2023/11/10.
//

import UIKit
import SwiftyJSON

typealias unreadblock = (_ num:Int)->Void
typealias RongCloudGetMessage = (_ message: RCMessage, _ left: Int32) -> Void

class COChatMsgManager: NSObject,RCIMConnectionStatusDelegate, RCIMReceiveMessageDelegate, RCIMUserInfoDataSource {

    static let shared = COChatMsgManager()
    
    var unreadBack:unreadblock?
    var rcGetMessageCallback: RongCloudGetMessage?
    
    weak var callViewController: COCallViewController?
    
    func initRCIM(){
        RCIM.shared().initWithAppKey(KRongCloudAppKey, option: nil)
        RCIM.shared().connectionStatusDelegate = self
        RCIM.shared().registerMessageType(COVideoContent.self)
        RCIM.shared().registerMessageType(COGiftContent.self)
    }
    
    func connectIM() {
        var model = COUserInfoManager.shared.curUser
        let imToken = model?.rcToken
        if imToken?.count ?? 0 > 0{
            connect(token: imToken!)
        }else {
            COHttpManager.request(target: COBaseApi.rcImtoken, modelType: CORongUserToken.self) { [weak self] code, object, success in
                model?.rcToken = (object?.user.token)!
                model?.rcUserId = (object?.user.userId)!
                COUserInfoManager.shared.curUser = model
                COUserInfoManager.coSaveInfo()
                self?.connect(token:(object?.user.token)!)
            } failureBlock: { code, msg in
                print("\(msg ?? "connect rongcloud error")")
            }
        }
    }
    
    private func connect(token:String) {
        RCIM.shared().connect(withToken: token, timeLimit: 0) { code in
            //消息数据库打开，可以进入到主页面
        } success: { userId in
            //连接成功
            self.updateInfoToIM()
            self.setBadgeValue()
        } error: { status in
            switch status {
            case .RC_CONN_DISPOSABLE_TOKEN_USED, .RC_CONN_TOKEN_EXPIRE, .RC_CONN_TOKEN_INCORRECT:
                var model = COUserInfoManager.shared.curUser
                model?.rcToken = ""
                self.connectIM()
                break
            default:
                break
            }
        }
    }
    
    func updateInfoToIM() {
        if let user = COUserInfoManager.shared.curUser {
            let rcuser = RCUserInfo(userId: "client_\(user.userResponse.id)", name: user.userResponse.nickName, portrait: user.userResponse.profilePhoto)
            RCIM.shared().currentUserInfo = rcuser
            RCIM.shared().addReceiveMessageDelegate(self)
            RCIM.shared().userInfoDataSource = self
            RCIM.shared().enableMessageAttachUserInfo = true
            RCIM.shared().enablePersistentUserInfoCache =  true
        }
    }
    
    // 设置角标
    func setBadgeValue(){
        let totalUnread = RCIMClient.shared().getTotalUnreadCount()
        if self.unreadBack != nil {
            self.unreadBack!(Int(totalUnread))
        }
    }
    
    /**
     *断开连接
     */
    func disconnection(){
        RCIM.shared().disconnect()
        RCIM.shared().logout()
        UIApplication.shared.applicationIconBadgeNumber = 0
    }
    
    func onRCIMConnectionStatusChanged(_ status: RCConnectionStatus) {
        switch status {
        case .ConnectionStatus_KICKED_OFFLINE_BY_OTHER_CLIENT:
            var model = COUserInfoManager.shared.curUser
            model?.token = ""
            model?.rcToken = ""
            COUserInfoManager.shared.curUser = model
            COUserInfoManager.coSaveInfo()
            KAppDelegate.setRootViewController()
            break
        default:
            break
        }
    }
    
    /*!
     SDK 的回调，用于向 App 获取用户信息
     @param userId      用户ID
     @param completion  获取用户信息完成之后需要执行的Block [userInfo:该用户ID对应的用户信息]
     @discussion SDK通过此方法获取用户信息并显示，请在completion中返回该用户ID对应的用户信息。
     在您设置了用户信息提供者之后，SDK在需要显示用户信息的时候，会调用此方法，向您请求用户信息用于显示。
     */
    func getUserInfo(withUserId userId: String!, completion: ((RCUserInfo?) -> Void)!) {
        if let userCache = RCIM.shared().getUserInfoCache(userId) {
            if (!userCache.name.isEmptyStr && !userCache.portraitUri!.isEmptyStr && !userCache.userId.isEmptyStr) {
                completion(userCache)
                return
            }
        }
        guard userId.range(of: "_") != nil else {
            return
        }
        let components = userId.components(separatedBy: "_")
        var params = [String:Any]()
        params["ids"] =  components.last
        let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
        let target = feed == true ? COBaseApi.getListUserInfo(param: params):COBaseApi.getListStreamerInfo(param: params)
        COHttpManager.request(target: target, modelType: COChatUsersModel.self) { code, object, success in
            let chatList = object?.users
            if chatList?.count ?? 0 > 0{
                let anchormodel = chatList!.first
                var name_priceDic = [String:Any]()
                name_priceDic["name"] = anchormodel?.name
                name_priceDic["price"] = anchormodel?.price
                name_priceDic["status"] = anchormodel?.status
                if let jsonString = dictionaryToString(dictionary: name_priceDic) {
                    let userInfo = RCUserInfo(userId: userId, name: jsonString, portrait: anchormodel?.profilePhoto)
                    RCIM.shared().refreshUserInfoCache(userInfo, withUserId: userId)
                    completion(userInfo)
                }else{
                    let userInfo = RCUserInfo(userId: userId, name: anchormodel?.name, portrait: anchormodel?.profilePhoto)
                    RCIM.shared().refreshUserInfoCache(userInfo, withUserId: userId)
                    completion(userInfo)
                }
            }
        } failureBlock: { code, msg in
        }
    }
    
    func onRCIMReceive(_ message: RCMessage!, left: Int32) {
        DispatchQueue.main.safeAsync {
            var curUsermodel = COUserInfoManager.shared.curUser
            let msgContent = message.content
            if let senderUserInfo = msgContent?.senderUserInfo {
                RCIM.shared()?.refreshUserInfoCache(senderUserInfo, withUserId: senderUserInfo.userId)
            }
            //isOffLine 是否是离线消息，只在接收消息的回调方法中有效，如果消息为离线消息，则为 YES ，其他情况均为 NO
            if message.conversationType == .ConversationType_CHATROOM || message.isOffLine == true{
                if self.rcGetMessageCallback != nil {
                    self.rcGetMessageCallback!(message, left)
                }
                return
            }
            self.setBadgeValue()
            guard let content = message.content else {
                return
            }
            // 收到视频消息
            if content.isMember(of: COVideoContent.self) {
                let videoMsg = message.content as! COVideoContent
                guard videoMsg.streamerID != nil else {
                    return
                }
                let call = kLiveCalling.keyGetNSDefaultsKey() as? Bool
                if call == true{
                    // 如果正在打电话则挂断其他电话
                    let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
                    let rongcloudId = feed == true ? "client_\(videoMsg.streamerID!)": "streamer_\(videoMsg.streamerID!)"
                    let params = [
                        "streamerId": "\(videoMsg.streamerID!)",
                        "customerId": curUsermodel?.userResponse.id
                    ]
                    let json = JSON(params)
                    if let jsonString = json.rawString() {
                        let message = RCCommandMessage(name: "hangup", data: jsonString)
                        RCIMClient.shared().sendMessage(.ConversationType_PRIVATE, targetId: rongcloudId, content: message, pushContent: nil, pushData: nil) { (messageId) in
                            print("--挂断电话--")
                        } error: { (errorCode, messageId) in
                            print("\(errorCode.rawValue)" + "\(messageId)")
                        }
                    }
                }else{
                    // 正在拨打电话
                    let call = COCallViewController()
                    var anchorModel = DGChatUserInfoModel()
                    anchorModel.id = String(videoMsg.streamerID!)     // 对方ID
                    anchorModel.name = videoMsg.streamerName!         // 对方昵称
                    anchorModel.price = videoMsg.cost ?? 0
                    anchorModel.profilePhoto = videoMsg.senderUserInfo?.portraitUri ?? ""
                    kLiveCalling.keySaveToNSDefaults(with: true)
                    call.anchorModel = anchorModel
                    let tabBar = UIApplication.shared.getKeyWindow()?.rootViewController as! COBaseTabbarController
                    let nav = tabBar.viewControllers?[tabBar.selectedIndex] as! COBaseNavigationController
                    nav.pushViewController(call, animated: true)
                    self.callViewController = call
                }
            }else{
                if self.rcGetMessageCallback != nil {
                    self.rcGetMessageCallback!(message, left)
                }
            }
        }
    }
    
}
